use crate::common::AppState;
use crate::error::AppError;
use jwt_simple::prelude::{Deserialize, Serialize};
use sqlx::FromRow;

#[derive(Serialize, Deserialize, Debug, Default, FromRow, Clone, PartialEq)]
pub struct MyFile {
    pub id: i32,
    pub name: String,
    pub path: String,
    pub size: i32,
    pub user_id: i32,
    pub file_type: String,
    pub created_at: String,
    pub updated_at: String,
}

impl AppState {
    pub async fn insert_file(&self, file: &MyFile) -> Result<u64, AppError> {
        //check the filename is exists
        let res: Option<MyFile> =
            sqlx::query_as("SELECT * FROM files WHERE name = ? AND user_id = ?")
                .bind(&file.name)
                .bind(file.user_id)
                .fetch_optional(&self.pool)
                .await?;
        if res.is_some() {
            return Err(AppError::InsertFileError("file name is exists".to_string()));
        }

        let result = sqlx::query(
            "INSERT INTO files (name, path, size, user_id, file_type) VALUES (?, ?, ?, ?, ?)",
        )
        .bind(&file.name)
        .bind(&file.path)
        .bind(file.size)
        .bind(file.user_id)
        .bind(&file.file_type)
        .execute(&self.pool)
        .await?;
        if result.rows_affected() == 1 {
            Ok(result.last_insert_id())
        } else {
            Err(AppError::InsertFileError("insert file error".to_string()))
        }
    }
}
